package com.onluy.frameworkcloud.aspect;


import com.onluy.frameworkcloud.data.util.InParam;
import com.onluy.frameworkcloud.system.annotation.ParamCheck;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;

public class ParamCheckAspect {
        protected Logger log =   LoggerFactory.getLogger(this.getClass());



    /**
     * 方法开始执行
     */
    public void beforMethod(){
        log.info( "====================ParamCheckAspect.doBefore 方法开始执行");
    }

        /**
         * 方法执行
         * @param pjp
         * @return
         * @throws Throwable
         */
        public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
            log.info( " >>>>>>>>>>>>>>>>>>>> ParamCheckAspect.around 方法执行");
            //日志实体对象
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

            // 拦截的实体类，就是当前正在执行的controller
            Object target = pjp.getTarget();
            // 拦截的方法名称。当前正在执行的方法
            String methodName = pjp.getSignature().getName();
            // 拦截的方法参数
            Object[] args = pjp.getArgs();
            // 拦截的放参数类型
            Signature sig = pjp.getSignature();
            MethodSignature msig = null;
            if (!(sig instanceof MethodSignature)) {
                log.info( " >>>>>>>>>>>>>>>>>>>> ParamCheckAspect.around 该注解只能用于方法");
                throw new IllegalArgumentException("该注解只能用于方法");
            }
            msig = (MethodSignature) sig;
            Class[] parameterTypes = msig.getMethod().getParameterTypes();

            Object object = null;
            Method method = null;
            try {
                method = target.getClass().getMethod(methodName, parameterTypes);
            } catch (NoSuchMethodException e1) {
                log.info( " >>>>>>>>>>>>>>>>>>>> ParamCheckAspect.around NoSuchMethodException "+e1.getMessage());
                e1.printStackTrace();
            } catch (SecurityException e1) {
                log.info( " >>>>>>>>>>>>>>>>>>>> ParamCheckAspect.around SecurityException "+e1.getMessage());
                e1.printStackTrace();
            }

            if (null != method) {
                // 判断是否包含自定义的注解，说明一下这里的ParamCheck就是我自己自定义的注解
                if (method.isAnnotationPresent(ParamCheck.class)) {
                    //获取方法指定的校验参数注解
                    ParamCheck paramCheck = method.getAnnotation(ParamCheck.class);

                    log.info(" >>>>>>>>>>>>>>>>>>>> ParamCheckAspect.around  Check start" );
                    //2、指定需要校验的参数
                    String checkmsg="";
                    InParam<String, Object> inParam =null;
                   for(Object arg :args ){
                       if(arg instanceof InParam ){
                           inParam= (InParam<String, Object>) arg;
                           break;
                       }
                   }
                    if(!StringUtils.isEmpty(paramCheck) && paramCheck.value().length > 0 && !"".equals(paramCheck.value()[0])){
                        String[] paras = paramCheck.value();
                        for (String para : paras) {
                            String[] ckstr=para.trim().split(":");
                            String name=ckstr[0];
                            String text=name;
                            log.info(" >>>>>>>>>>>>>>>>>>>> name:"+name+",text:"+text );
                            if(ckstr.length>1) {
                                text=ckstr[1];
                            }
                            String paraValue = null;
                            paraValue=request.getParameter(name);
                            if(paraValue==null && inParam!=null)paraValue=""+inParam.get(name);
                            log.info(" >>>>>>>>>>>>>>>>>>>> paraValue:"+paraValue  );
                            //不能为空
                            if(StringUtils.isEmpty(paraValue)){
                                checkmsg=  text + "不能为空！" ;
                                break;
                            }
                        }
                    }
                        //校验通过
                        if(StringUtils.isEmpty(checkmsg)){
                            object = pjp.proceed(args);
                        }
                        else{
                            throw new IllegalArgumentException("参数校验失败，"+checkmsg);
                        }
                } else {
                    log.info( " >>>>>>>>>>>>>>>>>>>> ParamCheckAspect.around 没有校验注解");
                    object = pjp.proceed(args);
                }
            } else {
                log.info( " >>>>>>>>>>>>>>>>>>>> ParamCheckAspect.around 不需要拦截直接执行");
                object = pjp.proceed(args);
            }
            return object;
        }


}
